package cn.sanli.manage.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.sanli.manage.WeChat.QywxForestClient;
import cn.sanli.manage.ex.ServiceException;
import cn.sanli.manage.mapper.data1.TWxAccessTokenMapper;
import cn.sanli.manage.pojo.Wechat.MessageTextDto;
import cn.sanli.manage.pojo.Wechat.QywxConfig;
import cn.sanli.manage.pojo.Wechat.TWxAccessToken;
import cn.sanli.manage.service.WechatService;
import cn.sanli.manage.web.ServiceCode;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Map;
import java.util.Objects;

/**
 * @version 1.0.0
 * @program: award-punish
 * @description: 微信推送业务实现类
 * @author: lsk
 * @create: 2023-12-07 09:42
 * @since jdk1.8
 **/
@Service
@Slf4j
public class WechatServiceImpl implements WechatService {

    @Resource
    private QywxConfig qywxConfig;

    @Resource
    private TWxAccessTokenMapper tWxAccessTokenMapper;
    @Resource
    private QywxForestClient qywxForestClient;


    /**
     * 微信推送个人方法
     *
     * @param touser  指定接收消息的成员，成员ID列表（多个接收者用‘|’分隔，最多支持1000个）。 特殊情况：指定为"@all"，则向该企业应用的全部成员发送
     * @param content 消息内容，最长不超过2048个字节，超过将截断（支持id转译） 必填
     * @return 响应信息
     */
    public Map<String, Object> sendMessage(String touser, String content) {
        if (StrUtil.isEmpty(touser)) {
            // 消息接收者为空
            return Maps.newHashMap();
        }

        MessageTextDto messageTextDto = new MessageTextDto();
        messageTextDto.setAgentid(qywxConfig.getAgentId());
        messageTextDto.setTouser(touser);
        messageTextDto.getText().setContent(content);

        String accessToken = getToken();

        //如果accessToken为空
        if (StrUtil.isEmpty(accessToken)) {
            throw new ServiceException(ServiceCode.ERROR_UNKNOWN, "未生成推送Token");
        }
        Map<String, Object> result = qywxForestClient.messageSend(messageTextDto, accessToken);

        return result;
    }

    /**
     * 获取token缓存方法
     *
     * @return 企微Token
     */

    public String getToken() {
        String token = "";
        String corpId = qywxConfig.getCorpId();
        String secret = qywxConfig.getCorpSecret();
        Map<String, Object> result = null;
        try {
            log.info("获取access_token开始......");
            //先从数据库查，有做有效时间判断，无重新拉取
            TWxAccessToken wxAccessToken = tWxAccessTokenMapper.getAccessToken(corpId, secret, "N");
            System.out.println(wxAccessToken);
            if (wxAccessToken != null) {
                //获取当前Token过期时间
                Date expiresTime = wxAccessToken.getExpiresTime();
                log.info("获取凭证有效期：{},当前时间是否小于有效时间：{}", expiresTime, new Date().before(expiresTime));
                if (new Date().before(expiresTime)) {   //当前时间小于有效时间
                    token = wxAccessToken.getAccessToken();
                } else {
                    result = getAccessToken(corpId, secret);
                    log.info("数据库有资源,从企微获取access_token结果:{}", result);

                    if (null != result) {
                        token = String.valueOf(result.get("access_token"));
                        wxAccessToken.setAccessToken(token);
                        wxAccessToken.setExpiresTime(DateUtil.offsetSecond(new Date(), (Integer) result.get("expires_in")));
                        log.info("更新access_token");
                        tWxAccessTokenMapper.updateAccessToken(wxAccessToken);
                    }
                }
            } else {//数据库没有记录，从企微拉取，拉取之后存入数据库
                //获取access_token
                result = getAccessToken(corpId, secret);
                //打印请求结果
                log.info("数据库无资源,从企微获取access_token结果:{}", result);


                //判断JSONObject是否为空
                if (null != result) {
                    //获取access_token
                    token = String.valueOf(result.get("access_token"));
                    //创建TWxAccessToken对象
                    wxAccessToken = new TWxAccessToken();
                    //设置企业ID
                    wxAccessToken.setCorpId(corpId);
                    //设置企业密钥
                    wxAccessToken.setCorpSecret(secret);
                    //设置access_token
                    wxAccessToken.setAccessToken(token);
                    //设置过期时间
                    wxAccessToken.setExpiresTime(DateUtil.offsetSecond(new Date(), (Integer) result.get("expires_in")));
                    //设置标记
                    wxAccessToken.setFlag("N");
                    //打印新增access_token
                    log.info("新增access_token");
                    //插入TWxAccessToken对象
                    tWxAccessTokenMapper.insert(wxAccessToken);
                }
            }
        } catch (Exception e) {
            log.error("获取token失败:{}", e.getMessage());
        }
        return token;
    }

    /**
     * 生成企微Token
     *
     * @param corpId     企业ID
     * @param corpSecret 企业秘钥
     * @return 企微Token
     */
   public Map<String, Object> getAccessToken(String corpId, String corpSecret) {

        // 调用企业微信接口获取access_token
        Map<String, Object> result = qywxForestClient.getToken(corpId, corpSecret);
       // 判断返回结果是否正确
        if (!result.get("errcode").equals(0) || Objects.isNull(result.get("access_token"))) {
            System.out.println("获取企业微信access_token失败!" + result.get("errmsg"));
        }
        return result;
    }
}
